package zhklappoint.initsys;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import net.jodah.expiringmap.ExpirationPolicy;
import net.jodah.expiringmap.ExpiringMap;
import zhklappoint.ZhklAppointApplication;
import zhklappoint.annotation.IgnoreAuth;
import zhklappoint.entity.TokenEntity;
import zhklappoint.service.TokenService;
import zhklappoint.util.Tools;

@Configuration
@ComponentScan(basePackageClasses = ZhklAppointApplication.class, useDefaultFilters = true)
public class WxApiInterceptors extends HandlerInterceptorAdapter {
	
	public static final String LOGIN_USER_KEY = "LOGIN_USER_KEY";
	
	private static ConcurrentHashMap<String, ExpiringMap<String, Integer>> book = new ConcurrentHashMap<>();
	
	@Autowired
	private TokenService tokenService;
//	@Autowired
//	private StringRedisTemplate srt;
	
	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
	}

	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) {
//		String userIp=Tools.getIP(request);
//		String ipTimes=srt.opsForValue().get("userIp:"+userIp+":");
//		if(!ObjectUtils.isEmpty(ipTimes)) {
//			srt.boundValueOps("userIp:"+userIp+":").increment(1);
//			srt.expire("userIp:"+userIp+":",1000 , TimeUnit.MILLISECONDS);//设置过期时间
//		}else {
//			srt.opsForValue().set("userIp:"+userIp+":", "1");
//			srt.expire("userIp:"+userIp+":",1000 , TimeUnit.MILLISECONDS);//设置过期时间
//		}
//		ipTimes=srt.opsForValue().get("userIp:"+userIp+":");
//		if(!ObjectUtils.isEmpty(ipTimes)&&Integer.valueOf(ipTimes)>5) {
//			return false;
//		}
		
		// 获取Map对象， 如果没有则返回默认值
        // 第一个参数是key， 第二个参数是默认值
        ExpiringMap<String, Integer> map = book.getOrDefault(request.getRequestURI(), ExpiringMap.builder().variableExpiration().build());
        Integer uCount = map.getOrDefault(request.getRemoteAddr(), 0);
 
//        System.out.println("uCount:"+uCount+"----request.getRemoteAddr():"+request.getRemoteAddr());
        if (uCount >= 5) { // 超过次数，不执行目标方法
         //这里的返回对象类型根据controller方法的返回方式一致
           return false;
        } else if (uCount == 0){ // 第一次请求时，设置开始有效时间
            map.put(request.getRemoteAddr(), uCount + 1, ExpirationPolicy.CREATED, 1000, TimeUnit.MILLISECONDS);
        } else { // 未超过次数， 记录数据加一
            map.put(request.getRemoteAddr(), uCount + 1);
        }
        book.put(request.getRequestURI(), map);
// 
//        // result的值就是被拦截方法的返回值
//        Object result = pjp.proceed();
		
		
		
      IgnoreAuth annotation;
      if (arg2 instanceof HandlerMethod) {
          annotation = ((HandlerMethod) arg2).getMethodAnnotation(IgnoreAuth.class);
      } else {
          return true;
      }
      //如果有@IgnoreAuth不验证token
      if (annotation != null) {
          return true;
      }
		String token = request.getHeader("T-Zhkl-Token");
		if(!ObjectUtils.isEmpty(token)) {
			TokenEntity te = tokenService.findByTokenAndIsdelete(token);
			if(ObjectUtils.isEmpty(te)) {//TODO token过期问题需要处理 || te.getExpireTime().getTime() < System.currentTimeMillis()
				return false;
			}
			if(!ObjectUtils.isEmpty(te.getUserId())) {
				request.setAttribute(LOGIN_USER_KEY, te.getUserId());
				return true;
			}
		}
		return false;

//		//支持跨域请求
//        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
//        response.setHeader("Access-Control-Max-Age", "3600");
//        response.setHeader("Access-Control-Allow-Credentials", "true");
//        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,X-Nideshop-Token,X-URL-PATH");
//        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
//
//        IgnoreAuth annotation;
//        if (handler instanceof HandlerMethod) {
//            annotation = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
//        } else {
//            return true;
//        }
//
//        //如果有@IgnoreAuth注解，则不验证token
//        if (annotation != null) {
//            return true;
//        }
//
//        //从header中获取token
//        String token = request.getHeader(LOGIN_TOKEN_KEY);
//        //如果header中不存在token，则从参数中获取token
//        if (StringUtils.isBlank(token)) {
//            token = request.getParameter(LOGIN_TOKEN_KEY);
//        }
//
//        //token为空
//        if (StringUtils.isBlank(token)) {
//            throw new ApiRRException("请先登录", 401);
//        }
//
//        //查询token信息
//        TokenEntity tokenEntity = tokenService.queryByToken(token);
//        if (tokenEntity == null || tokenEntity.getExpireTime().getTime() < System.currentTimeMillis()) {
//            throw new ApiRRException("token失效，请重新登录", 401);
//        }
//
//        //设置userId到request里，后续根据userId，获取用户信息
//        request.setAttribute(LOGIN_USER_KEY, tokenEntity.getUserId());

	}
	
}
